home *** CD-ROM | disk | FTP | other *** search
/ PC-Blue - MS DOS Public Domain Library / PC-Blue MS-DOS Public Domain Library - NYACC.iso / vol309 / jdutil.arc / RM.ASM < prev    next >
Encoding:
Assembly Source File  |  1986-08-14  |  21.5 KB  |  611 lines

  1.         TITLE RM - MSDOS FILE DELETE UTILITY
  2.         PAGE 55,132
  3. ;**********************************************************************
  4. ;       THIS PROGRAM DELETES ONE OR MORE FILES, OR (WITH THE /R SWITCH)
  5. ;    THE CONTENTS OF A WHOLE DIRECTORY.
  6. ;
  7. ;       USAGE (afn = ambiguous file name):
  8. ;
  9. ;               RM afn1 afn2 ...  - deletes the named file(s)
  10. ;
  11. ;       SWITCHES (OPTIONAL):
  12. ;
  13. ;        RM/F - remove write-protected files without warning
  14. ;
  15. ;        RM/I - query before each deletion
  16. ;
  17. ;               RM/R - allows deleting directories (recursively).
  18. ;               (this is DANGEROUS, especially without the /I switch)
  19. ;
  20. ;               RM/V - "verbose" mode, shows name of each file deleted.
  21. ;
  22. ;   TO BUILD RM.EXE:
  23. ;    MASM RM,RM,NUL,NUL
  24. ;    LINK RM,RM,NUL,ASM -C800
  25. ;
  26. ;       BY: JON DART
  27. ;           DEPARTMENT OF ANTHROPOLOGY
  28. ;           UCSD C-001
  29. ;        LA JOLLA, CA 92093
  30. ;
  31. ;    VERSION 1.3, 19-JUL-86  (FIXES GROSS BUGS IN WILDCARD HANDLING)
  32. ;    VERSION 1.2, 06-JUL-86  (CHANGES TO MEMORY ALLOC., ACCEPTS HYPHEN
  33. ;                 AS SWITCH CHAR., ASSEMBLES UNDER MASM 4.0)
  34. ;    VERSION 1.1, 03-JUL-86  (BUG FIXES)
  35. ;       VERSION 1.0, 30-JUN-86
  36. ;
  37. PATHSIZE EQU    65                      ;MAX. SIZE OF DOS PATHNAME, +1
  38. MAXLEVEL EQU    12                      ;MAX NESTING LEVEL FOR DIRECTORIES
  39. MAXARGS EQU     40                      ;MAXIMUM # OF COMMAND LINE ARGUMENTS
  40. PRGSIZE EQU     1800H                   ;MAX. SIZE OF CODE AND FIXED DATA
  41. TRUE    EQU     1
  42. FALSE   EQU     0
  43. CONFIRM EQU     FALSE                   ;"CONFIRM BEFORE DELETE" DEFAULT
  44. VERBOSE EQU     FALSE                   ;"VERBOSE" OPTION (DEFAULT VALUE)
  45. GOOFPROOF EQU    TRUE            ;CONFIRM BEFORE DELETING *.*
  46. BIT$DIR EQU     00010000B               ;BIT IN ATTRIBUTE FOR DIRECTORY
  47. BIT$RO  EQU     00000001B               ;BIT IN ATTRIBUTE FOR WRITE-PROTECT
  48.  
  49.         .XLIST
  50.         INCLUDE ASCII.DEF
  51.         INCLUDE MSDOS2.DEF
  52.     INCLUDE MACROS.DEF
  53.         .LIST
  54.  
  55. RMINFO  STRUC
  56. NEWDIR  DW      1 DUP (?)               ;FLAG, =1 IF NEW DIRECTORY CREATED
  57. PATHTYPE DB     2 DUP (?)               ;TYPE OF SOURCE (0 IF UFN)
  58. ARG     DB      PATHSIZE DUP (?)        ;FIRST ARGUMENT (SOURCE)
  59. SPATH   DB      PATHSIZE DUP (?)        ;SOURCE SEARCH PATH
  60. SPREFIX DB      PATHSIZE DUP (?)        ;SOURCE LEAD-IN PATH
  61. SCRATCH DB      PATHSIZE DUP (?)        ;SCRATCH AREA
  62. FULLNAME DB      PATHSIZE DUP (?)       ;UNAMBIGUOUS SOURCE NAME
  63. DTA     DB      128 DUP (?)             ;DTA FOR SEARCH FN.
  64. RMINFO  ENDS
  65. RMSTRUCSIZE EQU 5*PATHSIZE+135          ;SIZE OF STRUCTURE
  66.  
  67. DATA    SEGMENT WORD PUBLIC
  68. ;
  69. ;       FIXED DATA AREA:
  70. ;
  71. MSG1    DB 'RM Version 1.3 by Jon Dart (19-Jul-86)',CR,LF,CR,LF
  72.         DB 'USAGE:',CR,LF,CR,LF
  73.         DB 'RM [-F -I -R -V] file1 file2  ...      deletes the named file(s)',CR,LF,CR,LF
  74.         DB 'SWITCHES (OPTIONAL):',CR,LF,CR,LF
  75.     DB '-F   remove write-protected files without warning',CR,LF
  76.     DB CR,LF
  77.         DB '-I   query before delete',CR,LF
  78.         DB CR,LF
  79.         DB '-R   allow recursive deletion of directories',CR,LF
  80.     DB CR,LF
  81.     DB '-V   echo file names as they are deleted',CR,LF
  82.         DB 0
  83. MSG2    DB      ': file not found.',CR,LF,0
  84. MSG3    DB      ': directory.',CR,LF,0
  85. MSG4    DB      ' : OK to delete [Y or N]? ',0
  86. MSG5    DB      ": can't remove.",CR,LF,0
  87. MSG6    DB      ': file is R/O. ',0
  88. MSG6A    DB    'Are you SURE [Y or N]? ',0
  89. MSG7    DB      "Directories nested too deep.",CR,LF,0
  90. MSG8    DB      "Insufficient memory for buffers.",CR,LF,0
  91. MSG9    DB      ": Illegal switch.",CR,LF,0
  92. MSG10   DB      "Too many arguments.",CR,LF,0
  93. MSG11    DB    ' directory. Enter it [Y or N]? ',0
  94. MSG12    DB    ' directory. Delete it [Y or N]? ',0
  95. MSG13    DB    '? ',0
  96. WILD    DB    '*.*',0
  97. DATA    ENDS
  98.  
  99. STACK   SEGMENT PARA STACK
  100.         DB      512 DUP (?)
  101. STACK   ENDS
  102.  
  103. ;       VARIABLES AND BUFFER AREAS, STORED IN FREE MEMORY ABOVE PROGRAM,
  104. ;       RELATIVE TO "BASE" (DS AND ES WILL NORMALLY POINT TO START OF THIS AREA):
  105.  
  106. RBASE   EQU     2                       ;POINTER TO RMSTRUC IN RSTACK
  107. LEVEL   EQU     4                       ;RECURSION LEVEL
  108. DRIVE   EQU       6                       ;SOURCE DRIVE (0 = DEFAULT)
  109. IFLAG    EQU    8            ;CONFIRM FLAG
  110. FFLAG    EQU    10            ;FORCE FLAG
  111. RFLAG    EQU    12            ;RECUSIVE FLAG
  112. VFLAG   EQU     14                      ;VERBOSE FLAG
  113. CMDTAIL EQU     16                      ;STORAGE FOR COMMAND TAIL
  114. NUMARGS EQU     CMDTAIL+512                ;NUMBER OF ARGUMENTS ON COMMAND LINE
  115. ARGPTRS EQU     NUMARGS+2               ;POINTERS TO START OF ARGUMENTS
  116. RSTACK  EQU     ARGPTRS+(2*MAXARGS)     ;RECURSION STACK
  117. DATASIZE EQU    (RSTACK)+(MAXLEVEL*RMSTRUCSIZE)+256
  118.  
  119.         PAGE +
  120. CODE    SEGMENT BYTE PUBLIC
  121. ASSUME CS:CODE,DS:DATA ,ES:DATA ,SS:STACK
  122. EXTRN   CPYCNT:NEAR,UC:NEAR,UCSTR:NEAR,CRLF:NEAR
  123. EXTRN   ERRORMSG:NEAR,COUT:NEAR,CIN:NEAR,CLRCO:NEAR
  124. EXTRN   SKIPSP:NEAR,TYPTX:NEAR,ERRORMSG:NEAR,CLRCO:NEAR
  125. EXTRN   FIXPATH:NEAR,TYPE_DIR:ABS,TYPE_AFN:ABS
  126. EXTRN   TYPE_UFN:ABS,TYPE_DSP:ABS,TYPE_DRV:ABS,TYPE_UNK:ABS
  127. EXTRN    GETYORN:NEAR
  128.  
  129. ;*********************
  130. ;* MACRO DEFINITIONS *
  131. ;*********************
  132.  
  133. ADDR    MACRO   REG,OFFST               ;COMPUTE ADDRESS OFFSET FROM BASE REGISTER (BX)
  134.         MOV     REG,BX
  135.         ADD     REG,OFFSET OFFST
  136.         ENDM
  137.  
  138. ERROR   MACRO   ERRNUM                  ;SHOW ERROR MESSAGE
  139.         PUSH    DS
  140.         MOV     AX,DATA 
  141.         MOV     DS,AX
  142.         MOV     DX,OFFSET DATA :MSG&ERRNUM
  143.         CALL    ERRORMSG
  144.         POP     DS
  145.         ENDM
  146.  
  147. ;**********************
  148. ; PROGRAM ENTRY POINT *
  149. ;**********************
  150. ENTRY:
  151.         TEST_DOS2                       ;TEST FOR DOS 2.0, EXIT IF DOS 1
  152.         MOV     BX,(DATASIZE+PRGSIZE) SHR 4
  153.     MOV    AH,SET_BLOCK
  154.     INT    DOS            ;SET PROGRAM+BUFFER SIZE
  155.     JNB    MEMOK            ;IF OK
  156.         MOV     AX,DATA
  157.         MOV     DS,AX
  158.         MOV     DX,OFFSET MSG3
  159.         CALL    ERRORMSG                ;NOT ENOUGH MEMORY
  160.         JMP     EXIT2
  161. MEMOK:  MOV     AX,DS            ;GET DATA SEG
  162.     ADD    AX,PRGSIZE        ;ADD OFFSET TO BUFFER
  163.     MOV    ES,AX            ;SET EXTRA SEG TO POINT TO BUFFER
  164.         MOV     BX,OFFSET (80H)         ;GET BYTE COUNT FOR COMMAND LINE
  165.         CMP     [BX],BYTE PTR 0
  166.         JE      USEMSG                  ;IF NO COMMAND TAIL
  167.         PUSH    BX
  168.         MOV     DL,[BX]
  169.         MOV     DH,0
  170.         ADD     BX,DX
  171.         INC     BX
  172.         MOV     [BX],BYTE PTR 0         ;PUT 0 BYTE AT END OF COMMAND LINE
  173.         POP     BX
  174.         INC     BX
  175.         CALL    SKIPSP                  ;SKIP LEADING SPACES
  176.         JNC     L_2                     ;IF SOMETHING ON LINE
  177. USEMSG: ERROR   1
  178.         JMP     EXIT2
  179. L_2:
  180.         MOV     SI,BX
  181.         MOV     DI,OFFSET CMDTAIL
  182.         MOV     CX,128
  183.         CALL    CPYCNT                  ;SAVE COMMAND TAIL
  184.         MOV     AX,ES
  185.         MOV     DS,AX                   ;SET DATA SEG TO VARIABLE AREA
  186.         MOV     BYTE PTR DS:IFLAG,CONFIRM  ;SET CONFIRM FLAG DEFAULT
  187.         MOV     BYTE PTR DS:VFLAG,VERBOSE  ;SET VERBOSE FLAG DEFAULT
  188.     MOV    BYTE PTR DS:RFLAG,FALSE    ;SET RECURSIVE FLAG DEFAULT
  189.     MOV    BYTE PTR DS:FFLAG,FALSE       ;SET FORCE FLAG DEFAULT
  190.     MOV    WORD PTR DS:LEVEL,0    ;ZERO RECURSION LEVEL
  191.         MOV     BYTE PTR DS:DRIVE,0     ;SET DRIVE DEFAULT
  192. ;***************************
  193. ; COLLECT SWITCHES, IF ANY *
  194. ;***************************
  195.         MOV     BX,OFFSET CMDTAIL       ;POINT TO COMMAND TAIL
  196.         CALL    UCSTR                   ;MAKE UPPER-CASE
  197. NEXTSW:
  198.         CALL    SKIPSP
  199.         JB      USEMSG                  ;IF NOTHING ON LINE BESIDES SWITCHES
  200.         CMP     BYTE PTR [BX],'/'       ;SWITCH SPECIFIED?
  201.     JE    GOTSW            ;YES
  202.     CMP    BYTE PTR [BX],'-'    ;CHECK HYPHEN, TOO
  203.         JNE     NOSWITCH                ;NOPE
  204. GOTSW:
  205.         INC     BX                      ;SKIP OVER SWITCH CHAR.
  206.         CALL    SKIPSP                  ;SKIP LEADING BLANKS
  207.         JB      USEMSG                  ;IF NOTHING
  208.         CALL    UC                      ;MAKE SWITCH UPPER CASE
  209.     CMP    AL,'F'            ;FORCE SWITCH?
  210.     JE    FSWITCH
  211.         CMP     AL,'I'                  ;QUERY SWITCH?
  212.         JE      ISWITCH
  213.     CMP    AL,'R'            ;RECURSIVE SWITCH?
  214.     JE    RSWITCH
  215.         CMP     AL,'V'                  ;VERBOSE SWITCH?
  216.         JE      VSWITCH
  217.         CALL    COUT                    ;DISPLAY BAD CHAR.
  218.         ERROR   9                       ;ILLEGAL SWITCH
  219.         JMP     EXIT2
  220. FSWITCH:
  221.         MOV     AL,1
  222.         SUB     AL,BYTE PTR DS:FFLAG
  223.         MOV     BYTE PTR DS:FFLAG,AL    ;TOGGLE FFLAG
  224.         INC     BX                      ;SKIP SWITCH LETTER
  225.         JMP     NEXTSW
  226. ISWITCH:
  227.         MOV     AL,1
  228.         SUB     AL,BYTE PTR DS:IFLAG
  229.         MOV     BYTE PTR DS:IFLAG,AL    ;TOGGLE IFLAG
  230.         INC     BX                      ;SKIP SWITCH LETTER
  231.         JMP     NEXTSW
  232. RSWITCH:
  233.         MOV     AL,1
  234.         SUB     AL,BYTE PTR DS:RFLAG
  235.         MOV     BYTE PTR DS:RFLAG,AL    ;TOGGLE RFLAG
  236.         INC     BX                      ;SKIP SWITCH LETTER
  237.         JMP     NEXTSW
  238. VSWITCH:
  239.         MOV     AL,1
  240.         SUB     AL,BYTE PTR DS:VFLAG
  241.         MOV     BYTE PTR DS:VFLAG,AL    ;TOGGLE VFLAG
  242.         INC     BX                      ;SKIP SWITCH LETTER
  243.         JMP     NEXTSW
  244. ;************************************************************
  245. ; SCAN THE COMMAND LINE AND STORE POINTERS TO ALL ARGUMENTS *
  246. ;************************************************************
  247. NOSWITCH:
  248.         MOV     CX,0                    ;CX COUNTS # OF ARGUMENTS
  249.         MOV     SI,OFFSET DS:ARGPTRS    ;POINT TO ARG POINTER TABLE
  250. SAVEARG:
  251.         INC     CX                      ;BUMP ARGUMENT COUNT
  252.         CMP     CX,MAXARGS
  253.         JG      TOOMANY                 ;IF TOO MANY
  254.         MOV     DS:[SI],BX              ;SAVE POINTER TO ARG
  255.         ADD     SI,2                    ;ADVANCE TO NEXT TABLE ENTRY
  256. CNTARGS:
  257.         MOV     AL,DS:[BX]              ;GET CHAR. FROM COMMAND LINE
  258.         CMP     AL,0
  259.         JE      ENDLINE                 ;IF END OF LINE
  260.         COMPLIST <SPACE,TAB>,NEXTARG    ;SEE IF SPACE OR TAB
  261.         INC     BX
  262.         JMP     CNTARGS                 ;LOOP TILL DELIMITER FOUND
  263. NEXTARG:
  264.         CALL    SKIPSP                  ;SKIP SPACES AND TABS
  265.         JNB     SAVEARG                 ;IF NOT EOL, BACK TO TOP OF LOOP
  266. ENDLINE:
  267.         CMP     CX,0                    ;CHECK ARGUMENT COUNT
  268.         JG      ARGSOK                  ;IF AT LEAST 1
  269. NOARGS:
  270.         JMP     USEMSG                  ;GIVE USE MESSAGE
  271. TOOMANY:
  272.         ERROR   10                      ;TOO MANY ARGUMENTS (PRETTY UNLIKELY)
  273.         JMP     EXIT2
  274. ARGSOK: MOV     WORD PTR DS:NUMARGS,CX  ;SAVE NUMBER OF ARGUMENTS
  275.  
  276. ;*****************************************
  277. ;* LOOP, DELETING FILES IN ARGUMENT LIST *
  278. ;*****************************************
  279.         MOV     SI,OFFSET DS:ARGPTRS    ;POINT TO POINTER TABLE
  280. RM1ARG:
  281.         MOV     BX,DS:[SI]              ;GET POINTER TO ARG
  282.         PUSH    SI
  283.         PUSH    CX
  284.         CALL    RMARG                   ;DELETE IT
  285.         POP     CX
  286.         POP     SI
  287.         ADD     SI,2                    ;ADVANCE TO NEXT ARG POINTER
  288.         LOOP    RM1ARG                  ;LOOP TILL NO MORE ARGS TO DELETE
  289.         JMP     EXIT2
  290.  
  291. ;*******************
  292. ;* REMOVE ONE FILE *
  293. ;*******************
  294. RMARG   PROC   NEAR
  295.         MOV     BYTE PTR DS:DRIVE,0     ;SET DRIVE DEFAULT
  296.         MOV     DI,OFFSET RSTACK+ARG    ;COLLECT FILE NAME
  297.         MOV     AL,[BX+1]
  298.         CMP     AL,':'                  ;CHECK FOR DRIVE SPEC
  299.         JNE     GETARG
  300.         MOV     AL,[BX]                 ;GET DRIVE LETTER
  301.         SUB     AL,'A'-1                ;MAKE BINARY
  302.         MOV     BYTE PTR DS:DRIVE,AL    ;SAVE DRIVE
  303. GETARG: MOV     AL,[BX]                 ;COPY FROM [BX] TO [DI] UNTIL DELIMITER
  304.         COMPLIST <0,SPACE,TAB>,ENDARG
  305.         STOSB
  306.         INC     BX
  307.         JMP     GETARG
  308. ENDARG: MOV     AL,0
  309.         STOSB                           ;END ARG W. ZERO
  310.         MOV     WORD PTR DS:RBASE,RSTACK   ;SAVE OFFSET TO RSTACK
  311.         CALL    RMIT                    ;DO IT TO IT
  312.         RET
  313. RMARG   ENDP
  314.  
  315.         PAGE +
  316. ;*********************************************************************
  317. ; THIS ROUTINE REMOVES A FILE OR DIRECTORY WHOSE PATHNAME IS SPECIFIED
  318. ; IN FIELD 'ARG' OF A STRUCTURE OF TYPE 'RMSTRUC'.  'RBASE' POINTS
  319. ; TO THE START OF THE DATA STRUCTURE FOR THIS RECURSION LEVEL.
  320. ;
  321. RMIT    PROC    NEAR
  322.         MOV     BX,WORD PTR DS:RBASE    ;GET BASE ADDR. (POINTER TO RMINFO)
  323.         ADDR    DX,DTA
  324.         MOV     AH,SET_DTA
  325.         INT     DOS                     ;SET DTA
  326.         ADDR    CX,SPATH
  327.         ADDR    DX,SPREFIX
  328.         PUSH    BX
  329.         ADD     BX,OFFSET ARG
  330.         CALL    FIXPATH                 ;PARSE PATHNAME
  331.         POP     BX
  332.         CMP     AX,TYPE_UNK
  333.         JNE     GOODPATH                ;IF APPARENTLY OK
  334.         ADDR    DX,ARG
  335.         CALL    ERRORMSG
  336.         ERROR   2                       ;NONEXISTENT PATHNAME, COMPLAIN
  337.         RET
  338. GOODPATH:
  339.         MOV     WORD PTR [BX].PATHTYPE,AX     ;SAVE TYPE OF ARGUMENT
  340.     IF    GOOFPROOF
  341.     CMP    AX,TYPE_DRV        ;DRIVE SPEC?
  342.     JNE    NOTDRV            ;NO
  343.     CMP    BYTE PTR DS:IFLAG,TRUE    ;I FLAG SET?
  344.     JNE    GETOK            ;NO, GET OK
  345.     JMP    NOARGERR        ;ELSE GO AHEAD
  346.     ENDIF
  347. NOTDRV:
  348.     CMP    AX,TYPE_DIR        ;DIRECTORY?
  349.     JNE    NOTDIR
  350.     CMP    BYTE PTR DS:RFLAG,TRUE    ;R FLAG SET?
  351.     JNE    DIRERR            ;NO, ERROR
  352.     JMP    NOARGERR        ;YES, OK
  353. DIRERR:
  354.     ADDR    DX,ARG
  355.     CALL    ERRORMSG        ;SHOW ARGUMENT
  356.     ERROR    3            ;COMPLAIN THAT IT'S A DIRECTORY
  357.     RET
  358. NOTDIR:
  359.     IF    GOOFPROOF
  360.     CMP    AX,TYPE_AFN
  361.     JNE    NOARGERR        ;IF NOT AFN
  362.     CMP    BYTE PTR DS:LEVEL,0
  363.     JG    NOARGERR        ;IF LEVEL>0, DON'T CHECK FOR *.*
  364.     CMP    BYTE PTR DS:IFLAG,TRUE
  365.     JE    NOARGERR        ;DITTO IF I SWITCH SPECIFIED
  366.     CALL    CHECKWILD        ;CHECK FOR *.*
  367.     JNC    NOARGERR        ;IF SOMETHING ELSE
  368. GETOK:
  369.     ADDR    DX,SPATH
  370.     CALL    ERRORMSG        ;SHOW SEARCH PATH
  371.     ERROR    13    
  372.     ERROR    6A            ;USER TYPED *.*, ASK FOR CONFIRMATION
  373.     CALL    GETYORN
  374.     CMP    AL,'Y'
  375.     JE    NOARGERR        ;GO AHEAD IF 'Y' TYPED
  376.     JMP    EXIT2
  377.     ENDIF
  378. ;******************************************
  379. ; SEE IF ANYTHING MATCHES THE SEARCH SPEC *
  380. ;******************************************
  381. NOARGERR:
  382.         ADDR    DX,SPATH                ;POINT TO SEARCH PATH
  383.         MOV     CX,31H                  ;SET SEARCH ATTRIBUTES
  384.         MOV     AH,FIND_FIRST
  385.         INT     DOS                     ;SEARCH FOR 1ST MATCH
  386.         JNC     GOTONE                  ;OK IF SOMETHING FOUND
  387.         ADDR    DX,ARG
  388.         CALL    ERRORMSG                ;ELSE SHOW ARGUMENT
  389.         ERROR   2                       ;SAY IT DOESN'T EXIST
  390.     RET
  391. ;**************
  392. ; TOP OF LOOP *
  393. ;**************
  394. GOTONE:
  395.         CALL    BUILD_NAME              ;MAKE UNAMBIG. FILE NAME
  396.         JNC     NOSKIP
  397.         JMP     NEXTFILE                ;IF "FILE" IS "." OR ".." 
  398. NOSKIP:
  399.         TEST    [BX].DTA+21,BIT$DIR     ;IS THIS A DIRECTORY?
  400.         JNZ    GOTADIR            ;YES.
  401.     JMP    RMFILE            ;NO, IT'S A FILE
  402. ;*************************************************************
  403. ; IF ARG IS A DIRECTORY, AND R FLAG SET, DELETE ITS CONTENTS *
  404. ;*************************************************************
  405. GOTADIR:
  406.     CMP    BYTE PTR DS:RFLAG,TRUE    ;R FLAG SET?
  407.     JE    RSET            ;YES, OK TO DELETE DIRECTORY
  408.     JMP    NEXTFILE        ;NO, JUST SKIP OVER DIRECTORY
  409. RSET:
  410.     CMP    BYTE PTR DS:IFLAG,TRUE    ;I FLAG SET?
  411.     JNE    INOTSET            ;NO, GO INTO DIRECTORY
  412.     ADDR    DX,FULLNAME
  413.     CALL    ERRORMSG        ;SHOW DIRECTORY NAME
  414.     ERROR    11            ;ASK IF USER WANTS TO ENTER IT
  415.     CALL    GETYORN            ;GET RESPONSE
  416.     CMP    AL,'N'
  417.     JE    NEXTFILE        ;IF N TYPED
  418. INOTSET:
  419.         CMP     WORD PTR DS:LEVEL,MAXLEVEL-1 ;ARE WE AT MAX LEVEL?
  420.         JL      NOTMAX                  ;NO
  421.         ERROR   7                       ;YES, TOO DEEP
  422.         JMP     EXIT2
  423. NOTMAX:
  424.         COPYPATH FULLNAME,(ARG+RMSTRUCSIZE)  ;COPY DIRECTORY TO ARG AT NEXT LEVEL
  425.         PUSH    BX                      ;SAVE POINTER TO BASE
  426.         INC     WORD PTR DS:LEVEL       ;INCREMENT RECURSION LEVEL
  427.         ADD     WORD PTR DS:RBASE,RMSTRUCSIZE ;ADVANCE BASE POINTER
  428.         CALL    RMIT                    ;REMOVE THE DIRECTORY CONTENTS
  429.         POP     BX                      ;RESTORE BASE POINTER
  430.         DEC     WORD PTR DS:LEVEL       ;DECREMENT RECURSION LEVEL
  431.         SUB     WORD PTR DS:RBASE,RMSTRUCSIZE  ;RESTORE BASE TO PREVIOUS LEVEL
  432.         ADDR    DX,DTA
  433.         MOV     AH,SET_DTA
  434.         INT     DOS                     ;RESET DTA
  435.         JMP     SHORT NEXTFILE          ;DO NEXT FILE
  436. ;**************************
  437. ; FOUND A FILE, REMOVE IT *
  438. ;**************************
  439. RMFILE:
  440.         CMP     BYTE PTR DS:VFLAG,TRUE  ;CHECK VERBOSE FLAG
  441.         JNE     QUIET                   ;IF QUIET MODE
  442.         ADDR    DX,FULLNAME             ;NOT QUIET, SHOW VERBIAGE
  443.         CALL    ERRORMSG
  444.         CALL    CRLF
  445. QUIET:
  446.         CALL    RM_FILE
  447.     JNC    NEXTFILE
  448.     ADDR    DX,FULLNAME        ;IF ERROR, SHOW NAME
  449.     ERROR    5            ;AND ERROR MSG.
  450. ;*****************
  451. ; BOTTOM OF LOOP *
  452. ;*****************
  453. NEXTFILE:
  454.         MOV     AH,FIND_NEXT
  455.         INT     DOS                     ;FIND NEXT MATCH, IF ANY
  456.         JC      NOMORE                  ;IF NONE
  457.         JMP     GOTONE                  ;GOT ONE, BACK TO TOP OF LOOP
  458. ;*************************************************
  459. ; NO MORE FILES, DELETE DIRECTORY (IF NECESSARY) *
  460. ; ************************************************
  461. NOMORE:
  462.     CMP    WORD PTR [BX].PATHTYPE,TYPE_DIR    ;WAS THIS ARG A DIRECTORY?
  463.     JNE    DONE            ;NO, DONE
  464.     CMP    BYTE PTR DS:RFLAG,TRUE    ;RFLAG SET?
  465.     JNE    DONE            ;NO, DONE
  466.     ADDR    DX,ARG            ;POINT TO DIRECTORY NAME
  467.     CMP    BYTE PTR DS:IFLAG,TRUE    ;I FLAG SET?
  468.     JNE    NOI
  469.     CALL    ERRORMSG        ;DISPLAY DIRECTORY NAME
  470.     ERROR    12            ;ASK FOR OK TO DELETE
  471.     CALL    GETYORN            ;GET Y OR N RESPONSE
  472.     CMP    AL,'N'
  473.     JE    DONE            ;IF N, DON'T DELETE IT
  474. NOI:
  475.     ADDR    DX,ARG
  476.     MOV    AH,RMDIR        
  477.     INT    DOS            ;REMOVE DIRECTORY (IT SHOULD BE EMPTY NOW)
  478.     JNC    DONE            ;IF OK
  479.     ADDR    DX,ARG
  480.     CALL    ERRORMSG        ;ELSE SHOW DIRECTORY NAME
  481.     ERROR    5            ;AND ERROR MSG.
  482. DONE:
  483.         RET                             ;ALL DONE
  484. RMIT    ENDP
  485.  
  486. ;**************************************************
  487. ; CHECKWILD = CHECK ARG FOR *.* ERASURE
  488. ; RETURNS 'C' = 1 IF *.* ON WHOLE DIRECTORY OR DRIVE 
  489.  
  490. CHECKWILD PROC    NEAR
  491.     ADDR    SI,ARG            ;GET ARG
  492.     MOV    CX,0
  493. FINDEND:                ;FIND ITS END
  494.     CMP    BYTE PTR [SI],0
  495.         JE    GOTEND
  496.     INC    SI
  497.     INC    CX
  498.     JMP    SHORT FINDEND
  499. GOTEND:
  500.     CMP    CX,3
  501.     JL    NOTWIPE            ;IF <3 CHARS.
  502.     ADD    SI,-3            ;LOOK AT LAST PART OF ARGUMENT
  503.     CMP    CX,3
  504.     JE    CHECKIT2        ;IF =3 CHARS.
  505.     DEC    SI
  506.     CMP    BYTE PTR [SI],'\'    ;IF PREV. CHAR =
  507.     JE    CHECKIT            ;DIR SPEC
  508.     CMP    BYTE PTR [SI],':'
  509.     JE    CHECKIT            ;OR COLON, CHECK FOLLOWING STRING
  510.     CLC                ;OTHERWISE, ALLOW IT (SO TEST*.* IS
  511.     RET                ;NOT AN ERROR)
  512. CHECKIT:
  513.     INC    SI
  514. CHECKIT2:
  515.     PUSH    ES
  516.     CLD
  517.     MOV    AX,DATA 
  518.     MOV    ES,AX
  519.     MOV    DI,OFFSET ES:WILD       ;SEE IF WILD CARD *.*
  520. CMPMORE:
  521.     MOV    AL,BYTE PTR ES:[DI]
  522.     CMP    AL,0
  523.     JE    ENDCMP
  524.     CMPSB
  525.       JE    CMPMORE
  526.     POP    ES            ;BUG FIX!    v. 1.3
  527.     JMP    SHORT NOTWIPE        ;IF NOT =
  528. ENDCMP:
  529.     POP    ES
  530.     MOV    AL,BYTE PTR DS:[SI]
  531.     CMP    AL,0
  532.     JNE    NOTWIPE            ;IF NOT =
  533.     STC                ;WIPEOUT CITY
  534.     RET
  535. NOTWIPE:
  536.     CLC
  537.     RET
  538.  
  539. CHECKWILD ENDP
  540.  
  541.         PAGE +
  542. ;*****************************************************************************
  543. ; THIS ROUTINE TAKES THE INFO ON A FILE IN THE DTA AND USES IT TO GENERATE A
  544. ; FULL, UNAMBIGUOUS FILE NAME BY ADDING THE NECESSARY DIRECTORY PREFIXES TO IT.
  545. ; IT SETS THE CARRY FLAG IF THE "FILE" IS "." OR "..".
  546. ;
  547. BUILD_NAME  PROC  NEAR
  548.         COPYPATH SPREFIX,FULLNAME       ;GET SOURCE PREFIX, COPY TO FULL NAME
  549.         DEC     DI                      ;BACK UP OVER NULL
  550.         ADDR    SI,(DTA+30)             ;POINT TO FILE NAME WE FOUND
  551.         CMP     [SI],BYTE PTR '.'       ;DOES IT START WITH .? -
  552.         JNE     NOTDOT                  ;- NO
  553.         STC                             ;- YES, SET CARRY TO SKIP IT
  554.         RET
  555. NOTDOT:
  556.         CALL    CPYCNT                  ;ADD IT TO SOURCE PREFIX
  557.     CLC                ;CLEAR CARRY
  558.         RET
  559. BUILD_NAME ENDP
  560.  
  561. ;*************************************************************************
  562. ; REMOVE ONE FILE (NAME IS IN FIELD 'FULLNAME' OF THE 'RMSTRUC' POINTED TO
  563. ; BY BX).  RETURNS WITH CARRY SET IF ERROR.
  564. ;
  565. RM_FILE    PROC    NEAR
  566.         CMP     BYTE PTR DS:IFLAG,TRUE  ;IS FLAG SET TO CONFIRM?
  567.         JNE     COK                     ;NO.
  568.         ADDR    DX,FULLNAME
  569.         CALL    ERRORMSG                ;SHOW FILE
  570.         ERROR   4                       ;ASK FOR CONFIRMATION
  571.     CALL    GETYORN            ;GET Y OR N RESPONSE
  572.         CMP     AL,'Y'                  ;IS IT YES?
  573.         JNE     OKEXIT                  ;NO, RETURN W/O ERROR
  574. COK:
  575. TRYAGAIN:
  576.         ADDR    DX,FULLNAME
  577.         MOV     AH,UNLINK
  578.         INT     DOS                     ;UNLINK THAT SUCKER
  579.         JNC     OKEXIT                  ;IF NO PROBLEM
  580.         CMP     AX,5                    ;WAS FILE R/O? (THIS OUGHT TO BE
  581.                                         ; THE ONLY POSSIBLE ERROR)
  582.         JNE     ABEXIT                  ;EXIT IF SOME OTHER ERROR
  583.     CMP    BYTE PTR DS:FFLAG,TRUE    ;CHECK F FLAG
  584.     JE    NOWARN            ;IF SET, DON'T WARN ABOUT R/O FILE
  585.     ADDR    DX,FULLNAME
  586.     CALL    ERRORMSG        ;SHOW FILE NAME
  587.         ERROR   6                       ;R/O FILE, QUERY USER AGAIN
  588.     CALL    GETYORN            ;GET Y OR N RESPONSE
  589.         CMP     AL,'Y'                  ;TEST FOR 'Y' RESPONSE
  590.         JNE     OKEXIT                  ;QUIT (WITH NO ERROR) IF USER SAYS 'N'
  591. NOWARN:
  592.         MOV     CX,0                    ;'Y' TYPED CLEAR ALL ATTRIBUTES
  593.         ADDR    DX,FULLNAME             ;POINT TO FILE NAME
  594.         MOV     AH,CHMOD
  595.         MOV     AL,1                    ;CHANGE ATTRIBUTES
  596.         INT     DOS                     ;TRY MAKING IT R/W
  597.         JMP     TRYAGAIN                ;TRY TO ERASE IT AGAIN
  598. ABEXIT: STC
  599.         RET
  600. OKEXIT: CLC
  601.         RET
  602. RM_FILE    ENDP
  603.  
  604. EXIT2:
  605.         MOV     AH,EXIT
  606.         INT     DOS                     ;EXIT TO DOS
  607.  
  608. CODE    ENDS
  609.         END     ENTRY
  610.  
  611.